#include "Room.hh"
#include "Item.hh"
using namespace std;
#include <iostream>
#include <algorithm> // for std::find
Room::Room(const std::string& description)
    : description(description), north(nullptr), south(nullptr), east(nullptr), west(nullptr) {}

Room::~Room() {
    for (auto& item : items) {
        delete item;
    }
    for (auto& enemy : enemies) {
        delete enemy;
    }
}
Room::Room(const Room& other) {
    description = other.description;
    items = other.items; // Shallow copy, assuming Item has proper copy constructor
    enemies = other.enemies; // Shallow copy, assuming ICharacter has proper copy constructor
    north = other.north;
    south = other.south;
    east = other.east;
    west = other.west;
}
Room& Room::operator=(const Room& other) {
    if (this != &other) {
        description = other.description;
        items = other.items; // Shallow copy, assuming Item has proper copy constructor
        enemies = other.enemies; // Shallow copy, assuming ICharacter has proper copy constructor
        north = other.north;
        south = other.south;
        east = other.east;
        west = other.west;
    }
    return *this;
}

void Room::setDescription(const std::string& description) {
    this->description = description;
}

std::string Room::getDescription() const {
    return description;
}

void Room::addItem(Item* item) {
    items.push_back(item);
}

void Room::addEnemy(ICharacter* enemy) {
    enemies.push_back(enemy);
}

void Room::setNorth(Room* room) {
    north = room;
}

void Room::setSouth(Room* room) {
    south = room;
}

void Room::setEast(Room* room) {
    east = room;
}

void Room::setWest(Room* room) {
    west = room;
}

Room* Room::getNorth() const {
    return north;
}

Room* Room::getSouth() const {
    return south;
}

Room* Room::getEast() const {
    return east;
}

Room* Room::getWest() const {
    return west;
}
bool Room::hasEast() const {
    return east != nullptr;
}
bool Room::hasWest() const {
    return west != nullptr;
}
bool Room::hasNorth() const {
    return north != nullptr;
}
bool Room::hasSouth() const {
    return south != nullptr;
}
void Room::display() const {
    std::cout << description << std::endl;
    std::cout << "Items here: ";
    for (const auto& item : items) {
        std::cout << item->getName() << ", ";
    }
    std::cout << std::endl;
    std::cout << "Enemies here: ";
    for (const auto& enemy : enemies) {
        std::cout << enemy->toString() << ", ";
    }
    std::cout << std::endl;
}

void Room::generateRandomLoot() {
    items.push_back(Item::generateRandomItem());
}
// Remove the specified enemy
void Room::removeEnemy(ICharacter* enemy) {
    // Use std::find to compare pointer values
    auto it = std::find(enemies.begin(), enemies.end(), enemy);
    if (it != enemies.end()) {
        delete *it; 
        *it = nullptr; // Set the pointer to nullptr
        enemies.erase(it);
    }
}

//Remove the specified item
void Room::removeItem(Item* item) {
    // Use std::find to compare pointer value
    auto it = std::find(items.begin(), items.end(), item);
    if (it != items.end()) {
        delete *it; 
        *it = nullptr; // Set the pointer to nullptr
        items.erase(it);
    }
}

std::vector<ICharacter*> Room::getEnemies() const {
    std::vector<ICharacter*> validEnemies;
    for (auto& enemy : enemies) {
        if (enemy != nullptr) { // Filter null Pointers
            validEnemies.push_back(enemy);
        }
    }
    return validEnemies;
}

std::vector<Item*> Room::getItems() const {
    std::vector<Item*> validItems;
    for (auto& item : items) {
        if (item != nullptr) { // Filter null Pointers
            validItems.push_back(item);
        }
    }
    return validItems;
}